package com.xhtt.modules.cfg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhtt.common.exception.RRException;
import com.xhtt.common.exception.RRExceptionEnum;
import com.xhtt.common.utils.DateUtils;
import com.xhtt.common.utils.ExportExcel;
import com.xhtt.common.utils.PageUtils;
import com.xhtt.common.utils.Query;
import com.xhtt.modules.cfg.dao.CfgHoseInfoMapper;
import com.xhtt.modules.cfg.entity.CfgComprod;
import com.xhtt.modules.cfg.entity.CfgHoseInfo;
import com.xhtt.modules.cfg.entity.CfgHoseLog;
import com.xhtt.modules.cfg.entity.CfgHoseProduct;
import com.xhtt.modules.cfg.schedule.HoseLog;
import com.xhtt.modules.cfg.service.CfgComprodService;
import com.xhtt.modules.cfg.service.CfgHoseInfoService;
import com.xhtt.modules.cfg.service.CfgHoseLogService;
import com.xhtt.modules.cfg.service.CfgHoseProductService;
import com.xhtt.modules.inspection.service.IInsLabelService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 软管库 服务实现类
 * </p>
 *
 * @author feipc
 * @since 2019-02-20
 */
@Service
public class CfgHoseInfoServiceImpl extends ServiceImpl<CfgHoseInfoMapper, CfgHoseInfo> implements CfgHoseInfoService {

    @Autowired
    private CfgHoseProductService cfgHoseProductService;

    @Autowired
    private CfgComprodService cfgComprodService;

    @Autowired
    private IInsLabelService insLabelService;
    @Autowired
    private CfgHoseLogService hoseLogService;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<CfgHoseInfo> page = new Query<CfgHoseInfo>(params).getPage();
        page.setRecords(baseMapper.queryPage(page, params));
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void addHose(CfgHoseInfo cfgHoseInfo) {
        String numberNo = cfgHoseInfo.getNumberNo();
        int count = this.count(new LambdaQueryWrapper<CfgHoseInfo>().eq(CfgHoseInfo::getNumberNo, numberNo).ne(CfgHoseInfo::getStatus, -1));
        if (count > 0) {
            throw new RRException("编号已存在");
        }
        this.save(cfgHoseInfo);
        List<CfgHoseProduct> all = formHoseProduct(cfgHoseInfo);
        if (CollectionUtils.isNotEmpty(all)) {
            cfgHoseProductService.saveBatch(all);
        }

    }

    @Override
    @Transactional
    public void updateHose(CfgHoseInfo cfgHoseInfo) {
        int count = this.count(new LambdaQueryWrapper<CfgHoseInfo>().eq(CfgHoseInfo::getNumberNo, cfgHoseInfo.getNumberNo()).ne(CfgHoseInfo::getId, cfgHoseInfo.getId()).ne(CfgHoseInfo::getStatus, -1));
        if (count > 0) {
            throw new RRException("编号已存在");
        }

        CfgHoseInfo db = this.getById(cfgHoseInfo.getId());//取出对比 记日志
        this.updateById(cfgHoseInfo);
        //全删全增
        List<CfgHoseProduct> dbProducts = cfgHoseProductService.list(new LambdaQueryWrapper<CfgHoseProduct>().eq(CfgHoseProduct::getHoseId, cfgHoseInfo.getId()));//取出对比 记日志
        cfgHoseProductService.remove(new LambdaQueryWrapper<CfgHoseProduct>().eq(CfgHoseProduct::getHoseId, cfgHoseInfo.getId()));

        List<CfgHoseProduct> all = formHoseProduct(cfgHoseInfo);
        if (CollectionUtils.isNotEmpty(all)) {
            cfgHoseProductService.saveBatch(all);
        }
        taskExecutor.submit(new HoseLog(cfgHoseInfo, db, dbProducts, MDC.get("deptUser")));
    }

    @Override
    public void updateUsed(List<Integer> upHoseIds, Integer productId, String productName) {
        baseMapper.updateUsed(upHoseIds);
        baseMapper.updateCurProduct(upHoseIds, productId, productName);
    }

    @Override
    public List<CfgHoseInfo> validList(Integer productId, String pressureLevel) {
        return baseMapper.validList(productId, pressureLevel);
    }

    @Override
    public void flushProduct(List<Integer> hoseIdList) {
        baseMapper.flushProduct(hoseIdList);
    }

    private List<CfgHoseProduct> formHoseProduct(CfgHoseInfo cfgHoseInfo) {
        List<CfgHoseProduct> all = new ArrayList<>();
        Integer hoseId = cfgHoseInfo.getId();
        CfgHoseProduct comProduct = cfgHoseInfo.getComProduct();//页面没设置常用产品的话，也要构造这个对象并设置productid为null
        List<CfgHoseProduct> spareProducts = cfgHoseInfo.getSpareProducts();
        if (null == comProduct) {
            comProduct = new CfgHoseProduct();
        }
        comProduct.setType(1);
        comProduct.setHoseId(hoseId);
        all.add(comProduct);
        if (CollectionUtils.isNotEmpty(spareProducts)) {
            spareProducts.forEach(cfgHoseProduct -> {
                cfgHoseProduct.setType(2);
                cfgHoseProduct.setHoseId(hoseId);
            });
            all.addAll(spareProducts);
        }
        return all;
    }

    @Override
    public void upload(Map<Long, Map<Integer, String>> params) {

        Set<Integer> hasErrorLines = new HashSet<>();
        // 不存在的产品
        Set<String> productNoExist = new HashSet<>();

        params.forEach((k, v) -> {
            if (k > 2L) {
                boolean hasError = false;
                CfgHoseInfo cfgHoseInfo = new CfgHoseInfo();

                try {
                    // 软管编号
                    String numberNo = v.get(0);
                    if (StringUtils.isEmpty(numberNo)) {
                        hasError = true;
                    } else {
                        cfgHoseInfo.setNumberNo(numberNo);
                    }

                    // 长度
                    String length = v.get(1);
                    if (StringUtils.isEmpty(length)) {
                        hasError = true;
                    } else {
                        // excel 自动填充的单位不计算
                        cfgHoseInfo.setLength(Integer.parseInt(length/*.substring(0, length.length() - 1)*/));
                    }

                    // 位置
                    String position = v.get(2);
                    if (StringUtils.isNotEmpty(position)) {
                        cfgHoseInfo.setPosition(position);
                    }

                    // 压力等级
                    String pressureLevel = v.get(3);
                    if (StringUtils.isEmpty(pressureLevel)) {
                        hasError = true;
                    } else {
                        cfgHoseInfo.setPressureLevel(pressureLevel.equals("A类") ? 1 : 2);
                    }

                    // 常用产品
                    String common = v.get(4);
                    if (StringUtils.isNotEmpty(common)) {
                        CfgComprod cfgComprod = cfgComprodService.getByName(common);
                        if (cfgComprod == null) {
                            productNoExist.add(common);
                            hasError = true;
                        } else {
                            CfgHoseProduct cfgHoseProduct = new CfgHoseProduct();
                            cfgHoseProduct.setName(cfgComprod.getName());
                            cfgHoseProduct.setProductId(cfgComprod.getId());
                            cfgHoseInfo.setComProduct(cfgHoseProduct);
                        }
                    }

                    // 备用产品
                    String spare = v.get(5);
                    if (StringUtils.isNotEmpty(spare)) {
                        CfgComprod cfgComprod = cfgComprodService.getByName(common);
                        if (cfgComprod == null) {
                            hasError = true;
                            productNoExist.add(spare);
                        } else {
                            CfgHoseProduct cfgHoseProduct = new CfgHoseProduct();
                            cfgHoseProduct.setName(cfgComprod.getName());
                            cfgHoseProduct.setProductId(cfgComprod.getId());
                            cfgHoseInfo.setSpareProducts(Arrays.asList(cfgHoseProduct));
                        }
                    }

                    // 材质
                    String texture = v.get(6);
                    if (StringUtils.isNotEmpty(texture)) {
                        cfgHoseInfo.setTexture(texture);
                    }

                    // 保温
                    String insulation = v.get(7);
                    if (StringUtils.isNotEmpty(insulation)) {
                        cfgHoseInfo.setInsulation(insulation);
                    }

                    // rfid
                    String rfid = v.get(8);
                    if (StringUtils.isEmpty(rfid)) {
                        hasError = true;
                    } else {
                        cfgHoseInfo.setRfid(rfid);
                    }

                    // 采购日期
                    String datePurchase = v.get(9);
                    LocalDate purchase = null;
                    if (StringUtils.isNotEmpty(datePurchase)) {
                        LocalDateTime r = DateUtils.string2LocalDateTime(datePurchase, "yyyy/MM/dd");
                        purchase = r.toLocalDate();
                        cfgHoseInfo.setDatePurchase(purchase);
                    }

                    // 报废日期
                    String dateScrap = v.get(10);
                    if (StringUtils.isEmpty(dateScrap)) {
                        hasError = true;
                    } else {
                        if (purchase != null && dateScrap.contains("+")) {
                            String addDay = dateScrap.substring(dateScrap.indexOf("+"), dateScrap.length());
                            int day = Integer.parseInt(addDay);
                            cfgHoseInfo.setDateScrap(purchase.plusDays(day));
                        } else {
                            LocalDateTime r = DateUtils.string2LocalDateTime(dateScrap, "yyyy/MM/dd");
                            cfgHoseInfo.setDateScrap(r.toLocalDate());
                        }
                    }

                    // 上次打压日期
                    String dateSuppress = v.get(11);
                    if (StringUtils.isNotEmpty(dateSuppress)) {
                        LocalDateTime r = DateUtils.string2LocalDateTime(dateSuppress, "yyyy/MM/dd");
                        cfgHoseInfo.setDateSuppress(r.toLocalDate());
                    }
                    if (hasError) {
                        hasErrorLines.add(k.intValue());
                    } else {
                        this.addHose(cfgHoseInfo);
                    }
                } catch (Exception e) {
                    hasErrorLines.add(k.intValue());
                }
            }
        });
        StringBuilder stringBuilder = new StringBuilder();
        if (CollectionUtils.isNotEmpty(hasErrorLines)) {
            stringBuilder.append(insLabelService.formatUploadEx("第", hasErrorLines, "行有错误"));
        }
        if (CollectionUtils.isNotEmpty(productNoExist)) {
            stringBuilder.append(insLabelService.formatUploadEx("", productNoExist, "产品不存在"));
        }
        if (StringUtils.isNotEmpty(stringBuilder.toString())) {
            throw new RRException(stringBuilder.toString());
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response, Map<String, Object> params) {

        ExportExcel exportExcel = new ExportExcel();

        params.put("limit", "65000");

        PageUtils pageUtils = queryPage(params);
        List list = pageUtils.getList();
        String fileName = "软管数据";
        String sheetName = "sheet1";
        String[] headers = {"软管编号", "长度", "位置", "目前产品", "备用产品", "材质", "保温", "RFID", "采购日期", "报废日期", "上次打压日期"};
        String[] columns = {"numberNo", "length", "position", "comUsedProd", "SpareUsedProd", "texture", "insulation", "rfid", "datePurchase", "dateScrap", "dateSuppress"};
        try {
            exportExcel.exportExcel(fileName, sheetName, headers, columns, list, response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException(RRExceptionEnum.EXPORT_FAIL);
        }
    }

    @Override
    public void updateUnUsed(List<Integer> upHoseIds) {
        CfgHoseInfo hose = new CfgHoseInfo();
        hose.setUsed(0);
        this.update(hose, new LambdaQueryWrapper<CfgHoseInfo>().in(CfgHoseInfo::getId, upHoseIds));
    }

    @Override
    public PageUtils logList(Map<String, Object> params) {
        Page<CfgHoseLog> page = new Query<CfgHoseLog>(params).getPage();
        hoseLogService.page(page.setDesc("id"), new LambdaQueryWrapper<CfgHoseLog>().eq(CfgHoseLog::getHoseId, params.get("id")));
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void updateHoseRfid(CfgHoseInfo cfgHoseInfo) {
        CfgHoseInfo old = this.getById(cfgHoseInfo.getId());
        if (StringUtils.isEmpty(cfgHoseInfo.getRfid())) {
            this.update(new CfgHoseInfo(), new UpdateWrapper<CfgHoseInfo>().set(CfgHoseInfo.RFID, "").eq(CfgHoseInfo.ID, cfgHoseInfo.getId()));
        } else {
            this.updateById(cfgHoseInfo);
        }
        if (!ObjectUtils.nullSafeEquals(cfgHoseInfo.getRfid(), old.getRfid())) {
            String rfidInfo = old.getRfid() + " → " + cfgHoseInfo.getRfid();
            CfgHoseLog log = new CfgHoseLog();
            log.setHoseId(cfgHoseInfo.getId());
            log.setDeptUser(MDC.get("deptUser"));
            log.setPressureLevelInfo("");
            log.setRfidInfo(rfidInfo);
            log.setDateScrapInfo("");
            log.setDateSuppressInfo("");
            log.setComProductInfo("");
            log.setSpareProductInfo("");
            hoseLogService.save(log);
        }

    }
}
